﻿/** \file
* \par Subversion URL:
* \$URL: http://planar-rendering.googlecode.com/svn/trunk/frontend/src/Range.cs $
* \version \$Rev: 78 $
* \date    \$Date: 2009-04-20 09:47:39 +0000 (Mon, 20 Apr 2009) $
*/

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Frontend
{
	/// <summary>
	/// A class representing a potential range of values of a parameter, its
	/// resolution, etc.
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public class Range
	{
		/// <summary>A reference to the array of values for all ranges.</summary>
		public double[][] vals;
		/// <summary>The index in the value array to the value for this range.</summary>
		public int valsindex;
		/// <summary>The starting value presented to the user.</summary>
		public double presval;

		/// <summary>The resolution of this range.</summary>
		public int res = 1;
		/// <summary>The current index within this range during a generation session.</summary>
		public int[] resindex;

		/// <summary>Whether this range is to be mapped to a spatial dimension.</summary>
		public bool spatial;

		/// <summary>The low value for this range.</summary>
		public double low;
		/// <summary>The high value for this range.</summary>
		public double high;
		/// <summary>The delta value for this range.</summary>
		public double delta;

		/// <summary>The name of this range.</summary>
		public string name;

		/// <summary>
		/// The constructor.
		/// </summary>
		/// <param name="valsInit">A reference to the array of values for all ranges.</param>
		/// <param name="indexInit">The index in the value array to the value for this range.</param>
		public Range(double[][] valsInit, int indexInit)
		{
			resindex = new int[Generator.nthreads];
			vals = valsInit;
			valsindex = indexInit;
		}

		/// <summary>
		/// Calculate the delta value.
		/// </summary>
		public void SetDelta()
		{
			delta = (high - low) / (res-1);
		}

		/// <summary>
		/// Insert this range into a list of ranges sorted by resolution.
		/// </summary>
		/// <param name="list">The list into which this range will be inserted.</param>
		public void InsertResSorted(List<Range> list)
		{
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].res >= res)
				{
					list.Insert(i, this);
					return;
				}
			}
			list.Add(this);
		}

		/// <summary>
		/// Reset the values whose resolution=1.
		/// </summary>
		public void ResetSingleVals()
		{
			for (int t = 0; t < vals.Length; t++)
				vals[t][valsindex] = presval;
		}

		/// <summary>
		/// Reset the range values to their low end.
		/// </summary>
		public void ResetRangeVals()
		{
			for (int t = 0; t < vals.Length; t++)
				vals[t][valsindex] = low;
		}

		/// <summary>
		/// Reset the outermost range value based on the thread number.
		/// </summary>
		/// <param name="threadno">The thread number.</param>
		public void ResetFirstRangeVal(int threadno)
		{
			vals[threadno][valsindex] = (high - low) * threadno / Generator.nthreads + low;
			resindex[threadno] = res * threadno / Generator.nthreads;
		}

		/// <summary>
		/// Reset the range value to its low end.
		/// </summary>
		/// <param name="threadno">The thread number.</param>
		public void ResetRangeVal(int threadno)
		{
			vals[threadno][valsindex] = low;
			resindex[threadno] = 0;
		}

		/// <summary>
		/// Increment the range.
		/// </summary>
		/// <param name="threadno">The thread number.</param>
		public void IncrementVal(int threadno)
		{
			vals[threadno][valsindex] += delta;
			resindex[threadno]++;
		}
	}
}
